#include <iostream>
#include <unistd.h>
#include <vector>
#include <error.h>
#include <string>
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h>

using namespace std;
#define N 10
typedef void (*task)();
vector<task> vt; // 任务队列

void task1()
{
    cout << "检测当前角色健康状态" << endl;
}

void task2()
{
    cout << "检测当前角色物品补给" << endl;
}

void task3()
{
    cout << "检测当前角色生命值" << endl;
}

void task4()
{
    cout << "检测当前角色法力值" << endl;
}

void creator_task(vector<task> &vt)
{
    vt.push_back(task1);
    vt.push_back(task2);
    vt.push_back(task3);
    vt.push_back(task4);
}

class process
{
public:
    process(int id, const string &name, int fd)
        : id_(id), name_(name), fd_(fd)
    {
    }
    ~process()
    {
    }

public:
    pid_t id_;    // 子进程id
    string name_; // 子进程名称
    int fd_;      // 控制子进程的管道写端(真正控制子进程就是写端的文件描述符)
};

void chlid_go()//让子进程执行任务
{
    int task = 0;
    while (true)
    {
        int n = read(0, &task, sizeof(int));//读取的内容就是任务列表的下标
        if (n > 0)
        {
            cout << "处理该任务的进程是：" << getpid() << ":";
            vt[task]();//根据读取到的下标去调用任务列表里的函数指针
        }
        else
            break;
    }
}

void creator_pp(vector<process> &vpr)
{
    //vector<int> oldfd;
    for (int i = 0; i < N; i++)
    {
        int pipefd[2];
        int n = pipe(pipefd);
        if (n == -1)
        {
            perror("pipe");
            exit(-1);
        }

        // 创建子进程
        pid_t id = fork();
        if (id == 0)
        {
            //for(auto num:oldfd) close(num);
            close(pipefd[1]);
            dup2(pipefd[0], 0); // 重定向
            chlid_go();
            exit(0);
        }
        // 父进程代码
        close(pipefd[0]);
        string pro_name = "子进程" + to_string(i);
        vpr.push_back({id, pro_name, pipefd[1]});
        //oldfd.push_back(pipefd[1]);
    }
}

void test(vector<process> &vpr)
{
    for (auto &num : vpr)
    {
        cout << num.name_ << ":" << num.id_ << ":" << num.fd_ << endl;
    }
}

void clear(vector<process> &vpr)
{
    // for(int i = 0;i<vpr.size();i++)
    // {
    //     close(vpr[i].fd_);
    //     waitpid(vpr[i].fd_, nullptr, 0);
    //     sleep(1);
    // }
    // for(int i = vpr.size()-1;i>=0;i--)
    // {
    //     close(vpr[i].fd_);
    //     waitpid(vpr[i].fd_, nullptr, 0);
    //     sleep(1);
    // }
    for (auto fd : vpr)
    {
        close(fd.fd_);
        sleep(1);
        cout<<"正常关闭写端"<<endl;
    }
        sleep(3);
    for (auto fd : vpr)
        waitpid(fd.id_, nullptr, 0);
}